home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / VANESSA.C < prev    next >
Text File  |  1993-08-09  |  11KB  |  358 lines

  1. /* Vanessa Board Interface, 7.1.92
  2.  * implemented by Marcel Wiget, HB9RWM
  3.  * for NOS (Copyright 1991 Phil Karn, KA9Q)
  4.  *
  5.  * Vanessa is part of the project SEPRAN,
  6.  * Swiss Experimental Packet Radio Amateur Network,
  7.  * of the SWISS-ARTG (Swiss Amateur Radio Teleprinter Group).
  8.  * The full-size XT-Board contains 2 seperate interfaces
  9.  * for high-speed AX.25 Layer-2 data streams. The data
  10.  * can be received and sent via Dual-Port RAM embedded in a
  11.  * KISS - Frame. Result: very less overhead for NOS to receive
  12.  * and send a frame (e.g. only 1 memcpy for the hole frame).
  13.  *
  14.  * 10.11.91: Support of Vanessa Version 3.0 (word allignement RAM)
  15.  *           param command support
  16.  *           statistic support (e.g. if va0)
  17.  * 14.11.91: set of Node ID and Alias
  18.  *           safe waiting for cmd completion
  19.  * 19.11.91: info for 2nd port was wrong
  20.  * 20.11.91: download added
  21.  * 21.11.91: statistics for port 1 corrected, mbuf handling
  22.  * 17.11.91: some adaptions made for use with WNOS - DB3FL
  23.  * 24.11.91: dirps() and restore() inserted to mask interrupts
  24.  *           and changed buffer allocations and statistics
  25.  *           'param'-command adapted to WNOS strategy
  26.  *  7.01.92: if_param no longer supported by wnos, removed.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <dos.h>        /* for MK_FP */
  31. #include "global.h"
  32. #include "config.h"
  33. #ifdef VANESSA
  34. #include "proc.h"
  35. #include "commands.h"
  36. #include "mbuf.h"
  37. #include "ax25.h"
  38. #include "ip.h"         /* def. Ip_Addr */
  39. #include "pktdrvr.h"    /* def. for CL_AX25 */
  40. #include "trace.h"
  41. #include "vanessa.h"
  42.  
  43. static struct vandrvr Vandrvr[VAN_MAX];
  44.  
  45. static int van_stop __ARGS((struct iface *iface,int temp));
  46.  
  47. /* Attach a Vanessa interface to the system
  48.  * One board has 2 interfaces (Port 0 and 1)
  49.  * Each Port must have its own interface,
  50.  * attached via different dpram_base (dual port ram base address)
  51.  * argv[0]: hardware type, must be "vanessa"
  52.  * argv[1]: interface label, e.g., "va0"
  53.  * argv[2]: port-nr, started with 0,1: board 0, with 2,3: board 1 etc.
  54.  * argv[3]: maximum transmission unit, bytes (MTU) (optional)
  55.  */
  56.  
  57. int
  58. van_attach(int argc,char **argv,void *p)
  59. {
  60.         struct iface *ifvan;
  61.         struct vandrvr *vp;
  62.         struct dp_record far *dp;
  63.         unsigned char *cp;
  64.         int i;
  65.  
  66.         if(if_lookup(argv[1]) != NULLIF){
  67.                 tprintf(Ifexist,argv[1]);
  68.                 return -1;
  69.         }
  70.         if(*Mycall == '\0') {                         /* better to be sure */
  71.             tputs(Nomycall);
  72.             return -1;
  73.         }
  74.         for (i = 0; i < VAN_MAX; i++){
  75.                 if(Vandrvr[i].iface == NULLIF)
  76.                         break;
  77.         }
  78.         if (i >= VAN_MAX){
  79.                 tprintf("Max %d Vanessa drivers\n",VAN_MAX);
  80.                 return -1;
  81.         }
  82.         /* Create interface structure and fill in details */
  83.         ifvan = mxallocw(sizeof(struct iface));
  84.         ifvan->addr = Ip_addr;
  85.         ifvan->name = strxdup(argv[1]);
  86.         ifvan->mtu = (4 == argc) ? atoi(argv[3]) : 256;
  87.         setencap(ifvan,"AX25");
  88.         ifvan->ioctl = van_ioctl;
  89.         ifvan->status = van_status;
  90.         ifvan->raw = van_raw;
  91.         ifvan->stop = van_stop;
  92.         ifvan->hwaddr = strxdup(Mycall);
  93.         ifvan->dev = i;
  94.         vp = &Vandrvr[i];
  95.         vp->portnr = htoi(argv[2]);
  96.         vp->dpram_base = MK_FP(BASE_SEGMENT + (vp->portnr << 8),0);
  97.         vp->ioled = BASE_IO + (vp->portnr & 1) + (vp->portnr >> 1)*8 + 6;
  98.         vp->iores = BASE_IO + (vp->portnr >> 1)*8;
  99.         vp->iface = ifvan;
  100.         van_reset(vp);
  101.  
  102.         /* if port 0 of selected board, then */
  103.         /* set Node ID etc. */
  104.         dp = vp->dpram_base;
  105.         if (0 == (vp->portnr & 1)) {
  106.                 /* ok, let's do it */
  107.                 cp = (unsigned char *)(dp->dp_cData);
  108.                 memcpy(cp,Mycall,AXALEN);        /* MY_ID */
  109.                 cp += AXALEN;
  110.                 memcpy(cp,Mycall,AXALEN);               /* MY_ALIAS */
  111.                 cp += AXALEN;
  112.                 *cp = (0xff & vp->portnr);
  113.                 dp->dp_cCMD = CMD_ID_LOAD;
  114.         }
  115.  
  116.         outportb(vp->ioled,LED_OFF);
  117.  
  118.         /* init statistics */
  119.         vp->nTXwait     = 0;
  120.         vp->nRXmaxlen   = 0;
  121.         vp->nTXmaxlen   = 0;
  122.  
  123.         init_maxheard(ifvan);
  124.         init_flags(ifvan);
  125.  
  126.         ifvan->proc = newproc("van rx",256,van_rx,ifvan->dev,NULL,NULL,0);
  127.  
  128.         /* Link in the interface */
  129.         ifvan->next = Ifaces;
  130.         ifvan->niface = Niface++;               /* WNOS router */
  131.         Ifaces = ifvan;
  132.  
  133.         return 0;
  134. }
  135.  
  136. /* van_ioctl:
  137.  * perform device control on VANESSA KISS
  138.  */
  139. static int
  140. van_ioctl(struct iface *iface,int argc,char **argv)
  141. {
  142.         struct vandrvr *vp = &Vandrvr[iface->dev];
  143.         struct dp_record far *p = vp->dpram_base;
  144.         int pn = 0, v, i;
  145.  
  146.         if (2 == argc) {
  147.                 /* set value */
  148.                 pn = atoi(argv[0]);             /* param-nr to change */
  149.                 v = (int16)atoi(argv[1]);       /* value to be loaded */
  150.         }
  151.         for(i = 1;i < PARAM_COUNT; i++) {
  152.                 switch(i) {
  153.                 case TXDELAY:
  154.                         if (i==pn) {
  155.                                 p->dp_pTXDelay = v;
  156.                         } else {
  157.                                 tprintf("TxDelay %d\n", p->dp_pTXDelay);
  158.                         }
  159.                         break;
  160.                 case PERSIST:
  161.                         if (i==pn) {
  162.                                 p->dp_pPersist = v;
  163.                         } else {
  164.                                 tprintf("Persistence %d\n", p->dp_pPersist);
  165.                         }
  166.                         break;
  167.                 case SLOTTIME:
  168.                         if (i==pn) {
  169.                                 p->dp_pSlottime = v;
  170.                         } else {
  171.                                 tprintf("SlotTime %d\n", p->dp_pSlottime);
  172.                         }
  173.                         break;
  174.                 case TXTAIL:
  175.                         if (i==pn) {
  176.                                 p->dp_pTXTail = v;
  177.                         } else {
  178.                                 tprintf("TxTail %d\n", p->dp_pTXTail);
  179.                         }
  180.                         break;
  181.                 case FULLDUP:
  182.                         if (i==pn) {
  183.                                 p->dp_pDuplex = v;
  184.                         } else {
  185.                                 tprintf("Fullduplex %d\n", p->dp_pDuplex);
  186.                         }
  187.                         break;
  188.                 default:
  189.                         break;
  190.                 }
  191.                 if (pn){
  192.                         p->dp_reReadPar = 0;
  193.                 }
  194.         }
  195.         return 0;
  196. }
  197.  
  198. /* send raw data packet on KISS VANESSA */
  199. static int
  200. van_raw(struct iface *iface,struct mbuf *data)
  201. {
  202.         struct vandrvr *vp;
  203.         struct dp_record far *p;
  204.         int16 len = len_p(data);
  205.         int i_state;
  206.  
  207.         if (0 < len) {
  208.                 vp = &Vandrvr[iface->dev];
  209.                 dump(iface,IF_TRACE_OUT,CL_AX25,data);
  210.                 p = vp->dpram_base;
  211.                 if (0 == p->dp_oFProd)
  212.                         vp->nTXwait++;
  213.                 while ( (NULLIF != vp->iface) && (0 == p->dp_oFProd) ) {
  214.                         /* still busy, should not happen */
  215.                         pwait(NULL);
  216.                 }
  217.                 if (NULLIF != vp->iface) {
  218.                         /* send it */
  219.                         i_state = dirps();
  220.                         p->dp_oLFrm  = len;
  221.                         len = dqdata(data,(char *)&p->dp_oBuffer[0],len);
  222.                         if (len > vp->nTXmaxlen)
  223.                                 vp->nTXmaxlen = len;
  224.                         p->dp_oFProd = 0;                    /* send it */
  225.                         restore(i_state);
  226.                 }
  227.         } else
  228.                 free_p(data);
  229.         return 0;
  230. }
  231.  
  232. static void
  233. van_rx(int dev,void *p1,void *p2)
  234. {
  235.         struct vandrvr *vp = &Vandrvr[dev];
  236.         struct mbuf *rcvbuf;
  237.         struct phdr phdr;
  238.         struct dp_record far *p = vp->dpram_base;
  239.         char *cp;
  240.         int16 len;
  241.         int i_state;
  242.  
  243.         while (vp->iface != NULLIF){
  244.                 if (0 == p->dp_iFProd) {
  245.                         /* data arrived */
  246.                         len = p->dp_iLFrm;
  247.                         if (len > vp->nRXmaxlen)
  248.                                 vp->nRXmaxlen = len;
  249.                         if (len > 0) {
  250.                                 i_state = dirps();
  251.                                 outportb(vp->ioled,LED_ON);
  252.                                 rcvbuf = alloc_mbuf(len + sizeof(struct phdr));
  253.  
  254.                                 cp = rcvbuf->data + sizeof(struct phdr);
  255.                                 memcpy(cp,(char *)&p->dp_iBuffer[0],len);
  256.                                 rcvbuf->cnt = sizeof(struct phdr) + len;
  257.                                 rcvbuf->next = NULLBUF;
  258.                                 phdr.iface = vp->iface;
  259.                                 phdr.type = CL_AX25;
  260.                                 memcpy(rcvbuf->data,(char *)&phdr,sizeof(struct phdr));
  261.                                 restore(i_state);
  262.                                 enqueue(&Hopper,rcvbuf);
  263.                         }
  264.                         outportb(vp->ioled,LED_OFF);
  265.                         p->dp_iFProd = 1;       /* open DPRAM for next frame */
  266.                 }
  267.                 pwait(NULL);
  268.         }
  269. }
  270.  
  271. /* shut down the VANESSA interface */
  272. static int
  273. van_stop(struct iface *iface,int temp)
  274. {
  275.         struct vandrvr *vp = &Vandrvr[iface->dev];
  276.  
  277.         if (NULLIF != vp->iface) {
  278.                 vp->iface = NULLIF;
  279.         }
  280.         return 0;
  281. }
  282.  
  283. static void
  284. van_reset(struct vandrvr *vp)
  285. {
  286.         outportb(vp->iores,0xff);
  287.         pwait(NULL);
  288.         outportb(vp->iores,0);
  289. }
  290.  
  291.  
  292. static int32
  293. cova(char *p,int16 n)
  294. {
  295.         int  i;
  296.         int32 rv = 0;
  297.         n--;
  298.         for (i=n;i>=0;i--) rv = (rv<<8)+(p[i]&0xff);
  299.         return rv;
  300. }
  301.  
  302.  
  303. /* Show vanessa port status */
  304. static int
  305. van_status(struct iface *iface)
  306. {
  307.     struct vandrvr *vp = &Vandrvr[iface->dev];
  308.  
  309.     struct dp_record far *dp0 =
  310.         MK_FP(FP_SEG(vp->dpram_base)-((vp->portnr & 1)<<8),0);
  311.     struct dp_record far *dp1 =
  312.         MK_FP(FP_SEG(dp0)+0x0100,0);
  313.  
  314.     if (NULLIF != vp->iface) {
  315.         int i = 0, i_state = dirps();
  316.  
  317.         dp0->dp_cCMD = CMD_POINTER;
  318.  
  319.         while (i < CMD_TIMEOUT && dp1->dp_cCMD != (CMD_POINTER | 0xf000)) {
  320.             i++;
  321.             pwait(NULL);
  322.         }
  323.         if (CMD_TIMEOUT == i) {
  324.             tputs("No valid data\n");
  325.         } else {
  326.             char *cp = (char *)dp1->dp_cData;
  327.             tprintf("\n    Port %u: DP-RAM=%p TXwait=%u TXmaxlen=%u RXmaxlen=%u",
  328.                 vp->portnr,
  329.                 vp->dpram_base,
  330.                 vp->nTXwait,
  331.                 vp->nTXmaxlen,
  332.                 vp->nRXmaxlen);
  333.             tprintf("\n    SWrev=%x\.%02x Rst=%u Board=%u",
  334.                 cp[cRev+1],
  335.                 cp[cRev],
  336.                 cova(&cp[cRst],2),
  337.                 cp[cPNr] & 0xf);
  338.  
  339.             cp += (vp->portnr&1 ? cPort1 : 0);
  340.  
  341.             tprintf("    Counters: Rx=%lu Tx=%lu TxKu=%lu\n",
  342.                 cova(&cp[cRx],3),
  343.                 cova(&cp[cTx],3),
  344.                 cova(&cp[cTxKu],3));
  345.             tprintf("\n    RxBf TxBf RxBe TxBe RFlI TflC TFlI RCRC "
  346.                     "RxOv TxTo SyTx SyRx RxAb TxUdr\n   ");
  347.             for (i = cRxBf; i <= cTxUdr; i += 2)
  348.                 tprintf("%5u",cova(&cp[i],2));
  349.             tputs("\n");
  350.         }
  351.         restore(i_state);
  352.     }
  353.     return 0;
  354. }
  355.  
  356. #endif /* VANESSA */
  357.  
  358.